package com.hmall.order.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hmall.common.client.ItemClient;
import com.hmall.common.client.UserClient;
import com.hmall.common.dto.Address;
import com.hmall.common.dto.Item;
import com.hmall.order.mapper.OrderDetailMapper;
import com.hmall.order.mapper.OrderLogisticsMapper;
import com.hmall.order.mapper.OrderMapper;
import com.hmall.order.pojo.Order;
import com.hmall.order.pojo.OrderDetail;
import com.hmall.order.pojo.OrderLogistics;
import com.hmall.order.pojo.RequestParams;
import com.hmall.order.service.IOrderService;
import com.hmall.order.utils.BaseContext;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.nio.charset.StandardCharsets;
import java.util.Date;

@Service
public class OrderService extends ServiceImpl<OrderMapper, Order> implements IOrderService {


    @Autowired
    private ItemClient itemClient;

    @Autowired
    private UserClient userClient;

    @Autowired
    private RabbitTemplate rabbitTemplate;


    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Autowired
    private OrderLogisticsMapper orderLogisticsMapper;

    @Transactional(rollbackFor = Exception.class)
    public Order createOrder(RequestParams requestParams) {

        // 1.查询商品：远程调用商品服务根据ID查询商品详情
        Item item = itemClient.queryItemById(requestParams.getItemId());
        // 2.基于商品价格 * 购买数量计算商品总价：totalFee
        long totalFee = item.getPrice() * requestParams.getNum();


        //=====================新增==========================
        Order order = new Order();
        order.setTotalFee(totalFee); //总金额
        order.setPaymentType(requestParams.getPaymentType());
        order.setUserId(BaseContext.getCurrentId()); //获取当前用户ID
        order.setStatus(1); //设置状态为：未支付
        // 3.将Order写入数据库tb_order表中
        save(order); //保存成功后,框架底层：order.setId(xxx)
        //获取订单id：order.getId();

        // 4.将商品信息、orderId信息封装为OrderDetail对象，写入tb_order_detail表
        OrderDetail detail = new OrderDetail();
        //detail.setName(item.getName());
        //detail.setSpec(item.getSpec());
        //detail.setPrice(item.getPrice());
        //detail.setImage(item.getImage());
        //属性名一致，可以使用对象拷贝
        BeanUtils.copyProperties(item, detail, "id");
        //下面几个属性名不一致，必须使用set方法赋值
        detail.setOrderId(order.getId());
        detail.setItemId(item.getId());
        detail.setNum(requestParams.getNum());
        orderDetailMapper.insert(detail);

        //====================新增================
        // 5.远程调用：根据addressId查询user-service服务，获取地址信息
        Address address = userClient.findAddressById(requestParams.getAddressId());
        // 6.将地址封装为OrderLogistics对象，写入tb_order_logistics表
        OrderLogistics orderLogistics = new OrderLogistics();
        BeanUtils.copyProperties(address, orderLogistics);
        //两个属性名称不一致:order.id, order_detai.orderId，必须自己手动设置
        orderLogistics.setOrderId(order.getId());
        orderLogisticsMapper.insert(orderLogistics);

        // 远程调用：扣减库存
        try {
            //注意：传递负数，扣减库存
            itemClient.updateStock(requestParams.getItemId(), -requestParams.getNum());
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("库存不足！");
        }

        // 发送延迟消息，30分钟之后处理订单，如果没有支付就取消订单
        Message message = MessageBuilder
                .withBody(order.getId().toString().getBytes(StandardCharsets.UTF_8))
                //需要安装延迟插件：delayQueue
                .setHeader("x-delay", 1000 * 60 * 1) //设置延迟时间，单位毫秒
                .build();
        rabbitTemplate.send(
                "hmall.delay.direct", //延迟交换机名称
                "delay", //路由key
                message);//消息内容

        return order;
    }

    @Override
    public void dealExpireOrder(long orderId) {
        //1. 根据orderId查询订单
        Order order = this.getById(orderId);

        if(order == null){
            //订单不存在！
            return;
        }

        //2. 判断订单status是否为1
        if(order.getStatus() != 1){
            //订单状态不需要处理！
            return;
        }

        //3. 根据orderId查询订单详情，得到商品购买数量
        OrderDetail detail = orderDetailMapper.selectOne(
                Wrappers.<OrderDetail>lambdaQuery()
                        .eq(OrderDetail::getOrderId, orderId));
        Integer num = detail.getNum();
        Long itemId = detail.getItemId();

        //5.远程调用item-service，根据商品id、商品数量恢复库存
        itemClient.updateStock(itemId, num);

        //6.更新订单状态为5，记录关闭时间
        order.setCloseTime(new Date());
        order.setStatus(5); //已取消
        updateById(order);
    }
}
